<template>
  <BasicSelect
    v-bind="$attrs"
    :field-names="fieldNames"
    :options="options"
    :loading="loading"
    @options-change="handleChange"
  />
</template>

<script>
import { defineComponent, ref, watchEffect, nextTick } from 'vue'
import BasicSelect from './Select.vue'
import { isFunction, isArray, get } from 'lodash-es'
import { useGetInstance } from '@/hooks/web/usePage'

export default defineComponent({
  name: 'ApiSelect',
  components: { BasicSelect },
  props: {
    api: {
      type: Function,
      required: true
    },
    params: {
      type: [Object, String, Number],
      default: () => {}
    },
    resultField: {
      type: String,
      default: ''
    },
    // 是否立即请求
    immediate: {
      type: Boolean,
      default: true
    },
    fieldNames: {
      type: Object,
      default: () => ({ label: 'label', value: 'value' })
    },
    fomatterData: {
      type: Function,
      default: null
    },
    // 权限判断资源路径，不传则不进行资源权限校验
    authorize: {
      type: String,
      default: ''
    },
    getOptions: {
      type: Function,
      default: null
    }
  },
  emits: ['options-change'],
  setup(props, { emit }) {
    const vm = useGetInstance()
    const options = ref([])
    const loading = ref(false)

    watchEffect(() => {
      if (props.getOptions && isFunction(props.getOptions)) {
        props.getOptions(options.value)
      }
    })

    watchEffect(() => {
      nextTick(() => {
        let auth = true
        if (props.authorize && !vm?.$authorize(props.authorize)) {
          auth = false
        }
        props.immediate && auth && fetch()
      })
    })

    async function fetch() {
      const { api, params } = props

      if (!api && !isFunction(api)) return
      options.value = []
      try {
        const res = await api(params)
        if (isArray(res)) {
          options.value = res
        } else {
          props.resultField && (options.value = get(res, props.resultField) || [])
        }
        if (props.fomatterData && isFunction(props.fomatterData)) {
          options.value = props.fomatterData(options.value)
        }
      } catch (error) {
        options.value = []
        console.warn(error)
      }
    }

    function handleChange(e) {
      emit('options-change', e)
    }

    return {
      options,
      loading,
      handleChange
    }
  }
})
</script>
